package glock

import (
	"sync"
	"time"
)

// GlockMap is a simple implementation of GLock
type GlockMap struct {
	locks map[string]Lock
	mut   sync.Mutex
}

// NewGlockMap returns a new GlockMap
func NewGlockMap() *GlockMap {
	return &GlockMap{
		locks: make(map[string]Lock),
		mut:   sync.Mutex{},
	}
}

// Lock implements GLock.Lock
func (g *GlockMap) Lock(key string, expire time.Duration) bool {
	g.mut.Lock()
	defer g.mut.Unlock()

	// 如果锁已经存在，返判断是否过期
	if item, ok := g.locks[key]; ok {
		if item.ExpireAt.After(time.Now()) {
			return false
		}
	}

	g.locks[key] = Lock{
		Name:     key,
		ExpireAt: time.Now().Add(time.Second * expire),
	}

	return true
}

// Unlock implements GLock.Unlock
func (g *GlockMap) Unlock(key string) {
	g.mut.Lock()
	defer g.mut.Unlock()

	delete(g.locks, key)
}
